﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Sunny.UI;
using Sunny.UI.Win32;
using TVBox源合并工具.DTO;
using TVBox源合并工具.Properties;

namespace TVBox源合并工具
{
    public partial class MainForm : UIForm
    {
        #region 变量
        public List<Source> arrAllSource = new List<Source>();  //源
        public JArray arrAllSite = new JArray();  //站点
        public JArray arrAllLive = new JArray();  //直播

        public JArray arrMyLive = new JArray();  //我的直播

        public List<string> arrDownloadUrl = new List<string>();    //下载文件Url

        #endregion

        #region 构造函数
        public MainForm()
        {
            InitializeComponent();
        }
        #endregion

        //====================begin事件====================

        #region 初始化
        private void UIMainForm_Load(object sender, EventArgs e)
        {
            //加载源列表
            arrAllSource = JsonConvert.DeserializeObject<List<Source>>(Settings.Default.jsonSource);
            if (arrAllSource == null)
            {
                arrAllSource = new List<Source>();
            }
            this.SourceBindData(false);

            //加载点播列表
            arrAllSite = JsonConvert.DeserializeObject<JArray>(Settings.Default.jsonSite);
            if (arrAllSite == null)
            {
                arrAllSite = new JArray();
            }
            dgvSite.AutoGenerateColumns = false;
            dgvSite.DataSource = arrAllSite;

            //加载全部直播
            arrAllLive = JsonConvert.DeserializeObject<JArray>(Settings.Default.jsonLive);

            //加载点播列表
            arrMyLive = JsonConvert.DeserializeObject<JArray>(Settings.Default.jsonMyLive);
            if (arrMyLive == null)
            {
                arrMyLive = new JArray();
            }
            dgvLive.AutoGenerateColumns = false;
            dgvLive.DataSource = arrMyLive;
        }
        #endregion

        //====================源列表====================

        #region 添加源按钮
        private void btnAddSource_Click(object sender, EventArgs e)
        {
            AddSourceForm frm = new AddSourceForm();
            frm.type = 0;
            if (frm.ShowDialog() == DialogResult.OK)
            {
                int index = this.GetSourceIndex();
                Source source = new Source(index, frm.name, frm.path, frm.type);
                arrAllSource.Add(source);

                this.SourceBindData();

                //下载源文件
                if (this.DownloadSource(source))
                {
                    ShowSuccessDialog("提示", "下载完成", UIStyle.Blue);
                }
                else
                {
                    ShowSuccessDialog("提示", "下载失败", UIStyle.Blue);
                }
            }
        }
        #endregion

        #region 删除源按钮
        private void btnDeleteSource_Click(object sender, EventArgs e)
        {
            if (this.lstSource.SelectedItems.Count > 0)
            {
                if (ShowAskDialog("确定删除？"))
                {
                    List<int> arrIndex = new List<int>();
                    foreach (int index in this.lstSource.SelectedIndices)
                    {
                        arrIndex.Add(arrAllSource[index].Index);

                        //删除json文件
                        if (File.Exists(CommonData._SourceFile + arrAllSource[index].FileName))
                        {
                            File.Delete(CommonData._SourceFile + arrAllSource[index].FileName);
                        }

                        //删除jar文件
                        if (File.Exists(CommonData._JarFile + arrAllSource[index].JarName))
                        {
                            File.Delete(CommonData._JarFile + arrAllSource[index].JarName);
                        }

                        //删除lib文件夹
                        if (Directory.Exists(CommonData._LibFile + arrAllSource[index].Index))
                        {
                            Directory.Delete(CommonData._LibFile + arrAllSource[index].Index, true);
                        }
                    }

                    foreach (int index in arrIndex)
                    {

                        arrAllSource.RemoveAll(x => x.Index == index);
                    }

                    this.SourceBindData();
                }
            }
        }
        #endregion

        #region 下载源按钮
        private void btnDownloadSource_Click(object sender, EventArgs e)
        {
            StringBuilder msg = new StringBuilder();
            foreach (int index in this.lstSource.SelectedIndices)
            {
                Source source = arrAllSource[index];

                if (this.DownloadSource(source))
                {
                    msg.AppendLine($"【{source.Name}】下载成功！");
                }
                else
                {
                    msg.AppendLine($"【{source.Name}】下载失败！");
                }
            }
            if (msg.Length > 0)
            {
                ShowSuccessDialog("提示", msg.ToString(), UIStyle.Blue);
            }
        }
        #endregion

        #region 加载源按钮
        private void btnLoadSource_Click(object sender, EventArgs e)
        {
            StringBuilder msg = new StringBuilder();
            try
            {
                if (this.lstSource.SelectedItems.Count <= 0)
                {
                    ShowSuccessDialog("提示", "请选择源", UIStyle.Blue);
                    return;
                }

                this.ShowWaitForm("开始加载");
                int step = 1;
                foreach (int index in this.lstSource.SelectedIndices)
                {
                    this.SetWaitFormDescription($"加载中...（{step}/{this.lstSource.SelectedIndices.Count}）");
                    Source source = arrAllSource[index];

                    //检查文件是否存在
                    if (!File.Exists(CommonData._SourceFile + source.FileName))
                    {
                        msg.AppendLine($"【{source.FileName}】源文件不存在");
                        continue;
                    }

                    //读取Json数据
                    string json = File.ReadAllText(CommonData._SourceFile + source.FileName);
                    JObject obj = (JObject)JsonConvert.DeserializeObject(json);

                    //下载Jar(spider)
                    var temp = this.DownloadJar(source, obj["spider"].Value<string>(), 1);
                    if (temp == null)
                    {
                        msg.AppendLine($"【{source.FileName}】spider下载失败");
                        continue;
                    }
                    source.JarPath = temp;

                    //站点
                    this.AnalysisSite(source, obj, msg);

                    //解析
                    step += 1;
                }

                //保存数据
                this.SiteSaveData();

                dgvSite.DataSource = null;
                dgvSite.DataSource = arrAllSite;
            }
            catch (Exception)
            {
                msg.AppendLine("加载失败");
            }
            finally
            {
                this.HideWaitForm();
            }

            if (msg.Length > 0)
            {
                ShowSuccessDialog("提示", msg.ToString(),UIStyle.Blue);
            }
            else
            {
                ShowSuccessDialog("提示", "加载成功", UIStyle.Blue);
                this.Focus();
            }
        }
        #endregion

        #region 源列表--双击行
        private void lstSource_DoubleClick(object sender, EventArgs e)
        {
            if (this.lstSource.SelectedItems.Count > 0)
            {
                AddSourceForm frm = new AddSourceForm(
                    arrAllSource[lstSource.SelectedIndices[0]].Name,
                    arrAllSource[lstSource.SelectedIndices[0]].Path,
                    arrAllSource[lstSource.SelectedIndices[0]].Type
                );

                if (frm.ShowDialog() == DialogResult.OK)
                {
                    arrAllSource[lstSource.SelectedIndices[0]].Name = frm.name;
                    arrAllSource[lstSource.SelectedIndices[0]].Path = frm.path;
                    arrAllSource[lstSource.SelectedIndices[0]].Type = frm.type;

                    this.SourceBindData();
                }
            }
        }
        #endregion

        #region 导出按钮
        private void btnOutput_Click(object sender, EventArgs e)
        {
        }
        #endregion

        //====================点播列表====================

        #region 点播列表--Cell右键点击
        private void dgvSite_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e)
        {
            //右键点击，显示选择菜单
            if (e.Button == MouseButtons.Right && e.RowIndex > -1)
            {
                uiContextMenuStrip1.Show(MousePosition.X, MousePosition.Y);
            }
        }
        #endregion

        #region 点播列表--全选/取消全选
        private void chkSiteSelectAll_CheckedChanged(object sender, EventArgs e)
        {
            if (chkSiteSelectAll.Checked)
            {
                foreach (DataGridViewRow row in dgvSite.Rows)
                {
                    row.Cells[0].Value = true;
                }
            }
            else
            {
                foreach (DataGridViewRow row in dgvSite.Rows)
                {
                    row.Cells[0].Value = false;
                }
            }

            //保存数据
            this.SiteSaveData();
        }
        #endregion

        #region 点播列表--行选择/取消选择
        private void dgvSite_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex == 0 && e.RowIndex > -1)
            {
                dgvSite.EndEdit();
                var isSelect = (bool)dgvSite.Rows[e.RowIndex].Cells[0].EditedFormattedValue;
                if (isSelect)
                {
                    dgvSite.Rows[e.RowIndex].Cells[0].Value = false;
                }
                else
                {
                    dgvSite.Rows[e.RowIndex].Cells[0].Value = true;
                }

                //保存数据
                this.SiteSaveData();
            }
        }
        #endregion

        #region 点播列表--清空
        private void btnSiteClear_Click(object sender, EventArgs e)
        {
            if (arrAllSite.Count > 0)
            {
                if (ShowAskDialog("确定清空点播吗？"))
                {
                    arrAllSite.Clear();

                    //保存数据
                    this.SiteSaveData();
                }
            }
        }
        #endregion

        #region 点播列表--查询
        private void txtSiteSelect_DoEnter(object sender, EventArgs e)
        {
            string filter = txtSiteSelect.Text;
            if (string.IsNullOrEmpty(filter))
            {
                //显示所有行
                foreach (DataGridViewRow row in dgvSite.Rows)
                {
                    row.Visible = true;
                }
            }
            else
            {
                //解决选中行隐藏时报错问题
                CurrencyManager cm = (CurrencyManager)BindingContext[dgvSite.DataSource];
                cm.SuspendBinding();

                foreach (DataGridViewRow row in dgvSite.Rows)
                {
                    //根据名称过滤
                    DataGridViewCell cell = row.Cells["dgvSiteColumnName"];
                    if (cell.Value != null && cell.Value.ToString().Contains(filter))
                    {
                        row.Visible = true;
                        continue;
                    }

                    //根据Key过滤
                    cell = row.Cells["dgvSiteColumnKey"];
                    if (cell.Value != null && cell.Value.ToString().Contains(filter))
                    {
                        row.Visible = true;
                        continue;
                    }

                    row.Visible = false;
                }

                cm.ResumeBinding();
            }
        }
        #endregion

        //====================直播列表====================

        #region 直播列表--新增直播
        private void btnAddLive_Click(object sender, EventArgs e)
        {

        }
        #endregion

        #region 直播列表--删除直播
        private void btnDeleteLive_Click(object sender, EventArgs e)
        {

        }
        #endregion

        #region 直播列表--导入
        private void btnImportLive_Click(object sender, EventArgs e)
        {

        }
        #endregion

        //====================右键====================

        #region 右键菜单--选择
        private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e)
        {
            if (tabContent.SelectedIndex == 0)  //点播
            {
                foreach (DataGridViewRow row in dgvSite.SelectedRows)
                {
                    row.Cells[0].Value = true;
                }
            }
        }
        #endregion

        #region 右键菜单--取消选择
        private void toolStripMenuItemUnSelectAll_Click(object sender, EventArgs e)
        {
            if (tabContent.SelectedIndex == 0)  //点播
            {
                foreach (DataGridViewRow row in dgvSite.SelectedRows)
                {
                    row.Cells[0].Value = false;
                }
            }
        }
        #endregion

        //====================end事件====================

        //====================自定义函数====================

        #region 源列表--绑定数据
        private void SourceBindData(bool isSave = true)
        {
            this.lstSource.BeginUpdate();
            this.lstSource.Items.Clear();

            if (arrAllSource != null)
            {
                foreach (Source source in arrAllSource)
                {
                    this.lstSource.Items.Add(source.Name);
                }
            }

            this.lstSource.EndUpdate();

            if (isSave)
            {
                this.SourceSaveData();
            }
        }
        #endregion

        #region 源列表--保存
        private void SourceSaveData()
        {
            string strJson = JsonConvert.SerializeObject(arrAllSource);

            Settings.Default.jsonSource = strJson;
            Settings.Default.Save();
        }
        #endregion

        #region 源列表--取得序列号
        private int GetSourceIndex()
        {
            int index = 1;
            if (arrAllSource.Count > 0)
            {
                index = arrAllSource.Last<Source>().Index + 1;
            }
            return index;
        }
        #endregion

        #region 下载源文件
        private bool DownloadSource(Source source)
        {
            try
            {
                DirEx.CreateDir(CommonData._SourceFile);
                if (source.Type == 0)
                {
                    return HttpHelper.HttpGetSource(source.Path, CommonData._SourceFile + source.FileName);
                }
                else if (source.Type == 1)
                {
                    if (File.Exists(source.Path))
                    {
                        File.Copy(source.Path, CommonData._SourceFile + source.FileName, true);
                    }
                }

                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
        #endregion

        #region 下载Jar文件
        private string DownloadJar(Source source, string jarUrl, int type)
        {
            try
            {
                string jarPath = "";
                //相对路径时，补全
                if (jarUrl.Substring(0, 1) == ".")
                {
                    jarUrl = source.Url + jarUrl.Substring(1);
                }

                //截除md5
                if (jarUrl.Contains(";"))
                {
                    string[] temp = jarUrl.Split(";");
                    jarUrl = temp[0];
                    source.JarMd5 = temp[2];
                }

                if (type == 1)  //下载spider
                {
                    DirEx.CreateDir(CommonData._JarFile);
                    HttpHelper.HttpDownload(jarUrl, CommonData._JarFile + source.JarName);
                    jarPath = CommonData._JarFileRelative + source.JarName;
                }
                else if (type == 2) //下载点播站点中的jar
                {
                    var arrTemp = jarUrl.Split("/");
                    var jarFile = arrTemp[arrTemp.Length - 1];
                    arrTemp = jarFile.Split(".");
                    jarFile = arrTemp[0] + ".jar";
                    jarPath = CommonData._LibFileRelative + source.Index + "/" + jarFile;

                    if (!arrDownloadUrl.Contains(jarUrl))   //过滤重复下载
                    {
                        DirEx.CreateDir(CommonData._LibFile + source.Index + "/");
                        HttpHelper.HttpDownload(jarUrl, CommonData._LibFile + source.Index + "/" + jarFile);
                        arrDownloadUrl.Add(jarUrl);
                    }
                }
                return jarPath;

            }
            catch (Exception)
            {
                return null;
            }
        }
        #endregion

        #region 下载Lib文件
        private string DownloadLib(Source source, string libUrl)
        {
            try
            {
                string libPath = "";
                //相对路径时，补全
                if (libUrl.Substring(0, 1) == ".")
                {
                    libUrl = source.Url + libUrl.Substring(1);
                }

                var jarFile = libUrl.Substring(libUrl.LastIndexOf("/") + 1);

                libPath = CommonData._LibFileRelative + source.Index + "/" + jarFile;

                if (!arrDownloadUrl.Contains(libUrl))   //过滤重复下载
                {
                    DirEx.CreateDir(CommonData._LibFile + source.Index + "/");
                    HttpHelper.HttpDownload(libUrl, CommonData._LibFile + source.Index + "/" + jarFile);
                    arrDownloadUrl.Add(libUrl);
                }
                return libPath;
            }
            catch (Exception)
            {
                return null;
            }
        }
        #endregion

        #region 下载Live文件
        private bool DownloadLive(Source source, string liveUrl, string liveFile)
        {
            try
            {
                //相对路径时，补全
                if (liveUrl.Substring(0, 1) == ".")
                {
                    liveUrl = source.Url + liveUrl.Substring(1);
                }

                DirEx.CreateDir(CommonData._LibFile + source.Index + "/");
                HttpHelper.HttpDownload(liveUrl, CommonData._LibFile + source.Index + "/" + liveFile);
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
        #endregion

        #region 点播列表--解析站点数据
        private void AnalysisSite(Source source, JObject obj, StringBuilder msg)
        {
            arrDownloadUrl = new List<string>();
            var arrSite = obj["sites"].Value<JArray>();

            foreach (var site in arrSite)
            {
                var key = source.Name + "_" + site["key"].ToString();

                //删除已存在Key
                var filters = arrAllSite.Where(x => x["key"].ToString() == key).ToList();
                if (filters.Count > 0)
                {
                    site["isSelect"] = filters[0]["isSelect"];   //选择
                    arrAllSite.Remove(filters[0]);
                }
                else
                {
                    site["isSelect"] = 0;   //选择
                }

                site["source"] = source.Name;   //源
                site["key"] = key;

                //类型
                if (site["type"] != null)
                {
                    switch (site["type"].ToString())
                    {
                        case "0":
                            site["typename"] = "Xml";
                            break;
                        case "1":
                            site["typename"] = "Json";
                            break;
                        case "2":
                            site["typename"] = "爬虫源";
                            break;
                        case "3":
                            site["typename"] = "自定义爬虫";
                            break;
                        case "4":
                            site["typename"] = "服务器爬虫";
                            break;
                    }
                }
                else
                {
                    site["typename"] = "";
                }

                //搜索
                if (site["searchable"] != null)
                {
                    switch (site["searchable"].ToString())
                    {
                        case "0":
                            site["searchablename"] = "否";
                            break;
                        case "1":
                            site["searchablename"] = "是";
                            break;
                    }
                }
                else
                {
                    site["searchablename"] = "";
                }

                //快速搜索
                if (site["quickSearch"] != null)
                {
                    switch (site["quickSearch"].ToString())
                    {
                        case "0":
                            site["quickSearchname"] = "否";
                            break;
                        case "1":
                            site["quickSearchname"] = "是";
                            break;
                    }
                }
                else
                {
                    site["quickSearchname"] = "";
                }

                //筛选
                if (site["changeable"] != null)
                {
                    switch (site["changeable"].ToString())
                    {
                        case "0":
                            site["changeablename"] = "否";
                            break;
                        case "1":
                            site["changeablename"] = "是";
                            break;
                    }
                }
                else
                {
                    site["changeablename"] = "";
                }

                //jar
                if (site["jar"] != null)
                {
                    //下载Jar
                    var temp = this.DownloadJar(source, site["jar"].ToString(), 2);
                    if (temp == null)
                    {
                        msg.AppendLine($"【{source.Name}】的点播【{site["name"]}】Jar下载失败");
                        continue;
                    }
                    site["jar"] = temp;
                }
                else
                {
                    site["jar"] = source.JarPath;
                }

                //api
                if (site["api"] != null)
                {
                    string api = site["api"].ToString();
                    if (api.LastIndexOf("/") > -1)
                    {
                        string temp = api.Substring(api.LastIndexOf("/"));
                        if (temp.Contains("."))
                        {
                            temp = temp.Substring(temp.LastIndexOf('.') + 1);
                            if (temp == "js")
                            {
                                temp = this.DownloadLib(source, api);

                                if (temp == null)
                                {
                                    msg.AppendLine($"【{source.Name}】的点播【{site["name"]}】Api下载失败");
                                    continue;
                                }
                                site["api"] = temp;
                            }
                        }
                    }
                }

                //ext
                if (site["ext"] != null && !site["ext"].HasValues)
                {
                    string ext = site["ext"].ToString();
                    if (ext.LastIndexOf("/") > -1 && !ext.Contains("127.0.0.1") && !ext.Contains("$$$"))    //ext配置文件下载
                    {
                        string temp = ext.Substring(ext.LastIndexOf("/"));
                        if (temp.Contains("."))
                        {
                            temp = temp.Substring(temp.LastIndexOf('.') + 1);
                            if (temp == "js" || temp == "json")
                            {
                                temp = this.DownloadLib(source, ext);

                                if (temp == null)
                                {
                                    msg.AppendLine($"【{source.Name}】的点播【{site["name"]}】Ext下载失败");
                                    continue;
                                }
                                site["ext"] = temp;
                            }
                        }
                    }
                    else if (ext.Contains("127.0.0.1")) //ext配置本地token文件统一修改
                    {
                        string temp = ext;
                        if (ext.Contains("+"))
                        {
                            temp = ext.Substring(0, ext.LastIndexOf("+"));
                        }
                        else if (ext.Contains("$$$"))
                        {
                            temp = ext.Substring(0, ext.LastIndexOf("$$$"));
                        }
                        site["ext"] = ext.Replace(temp, "http://127.0.0.1:9978/file/tvbox/token.txt");
                    }
                }

                arrAllSite.Add(site);
            }
        }
        #endregion

        #region 点播列表--保存
        private void SiteSaveData()
        {
            Settings.Default.jsonSite = JsonConvert.SerializeObject(arrAllSite);
            Settings.Default.Save();
        }
        #endregion

        #region 直播列表--解析直播数据
        private void AnalysisLive(Source source, JObject obj, StringBuilder msg)
        {
            var arrLive = obj["lives"].Value<JArray>();

            for (int i = 0; i < arrLive.Count; i++)
            {
                if (arrLive[i]["name"] != null)
                {
                    var url = arrLive[i]["url"].ToString();
                    string liveFile = $"live_{i.ToString()}.txt";
                    this.DownloadLive(source, url, liveFile);
                }
            }

        }
        #endregion

    }
}
